package mspbots.data.sync.contactscience.receivers;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mspbots.data.sync.BaseReceiver;
import mspbots.data.sync.ResultMessageModel;
import mspbots.data.sync.contactscience.model.ContactScienceAppointments;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;
import java.util.Optional;

/**
 * @author Jay Yang
 */
@Log4j2
@Component
@RequiredArgsConstructor
public class ContactScienceAppointmentsReceiver extends BaseReceiver {
    private SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy KK:mmaa", Locale.ENGLISH);
    private SimpleDateFormat sdf1 = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss", Locale.ENGLISH);

    @RabbitListener(queues = "contactscience.appointments.sync")
    public void processAppointments(ResultMessageModel model) {
        log.debug("processAppointments[contactscience.appointments.sync] ResultMessageModel {}", model);
        if (!ObjectUtils.isEmpty(model.getEntity()) && ResultMessageModel.MessageModelAction.ADD.equals(model.getAction())) {
            Iterator<JsonNode> setAppointments = model.getEntity().get("setAppointments").elements();
            Iterator<JsonNode> scheduledAppointments = model.getEntity().get("scheduledAppointments").elements();
            while (setAppointments.hasNext()){
                processData(model, setAppointments,"setAppointments");
            }
            while (scheduledAppointments.hasNext()){
                processData(model, scheduledAppointments,"scheduledAppointments");
            }
        }
    }

    private void processData(ResultMessageModel model, Iterator<JsonNode> appointments,String type) {
        JsonNode next = appointments.next();
        ContactScienceAppointments data = ContactScienceAppointments.builder()
                .otherId(next.get("id").asText())
                .owner(model.getEntity().get("owner").asText())
                .type(type)
                .build();
        data.setExtend(next);
        data.setTenantId(model.getTenantId());
        data.setSyncTime(LocalDateTime.now());
        if (!ObjectUtils.isEmpty(next.findValue("lastChange"))){
            try {
                Date d2 = sdf.parse(next.findValue("lastChange").asText());
                String lastChange = sdf1.format(d2).replace(" ", "T").replaceFirst("0","2");
                data.setUpdateTime(LocalDateTime.parse(lastChange,DateTimeFormatter.ISO_DATE_TIME));
            } catch (ParseException e) {
                log.error(e.getMessage());
                data.setUpdateTime(null);
            }
        }
        Optional<Long> id = this.databaseClient.execute("select id from contactscience_appointments " +
                "where tenant_id =:tenantId and other_id =:otherId")
                .as(Long.class)
                .bind("tenantId", data.getTenantId())
                .bind("otherId", data.getOtherId())
                .fetch().one().blockOptional(Duration.ofSeconds(10));
        if (id.isPresent() && id.get() > 0) {
            data.setId(id.get());
            this.databaseClient.update().table(ContactScienceAppointments.class).using(data).fetch().rowsUpdated().block();
        } else {
            this.databaseClient.insert().into(ContactScienceAppointments.class).using(data).fetch().rowsUpdated().block();
        }
    }
}
